#include "memory.h"

//static UINT8 code[] = { (UINT8) 0x2E, (UINT8) 0x06, (UINT8) 0x26, (UINT8) 0x80, 0x36, 0x0A, (UINT8)0x06, (UINT8) 0x40, (UINT8)0x70, (UINT8)0x56, 0x3A, 0x06, 0x80};

static UINT8 code[] = { 0x11, 0x80, 0x0A, 0x00, 0x00, 0x2E, 0x06, 0x26, 0x80, 0x36, 0x0A};
static UINT8 *ram = (UINT8*) malloc(8192);

MEM_MAP memory;

UINT16 rom_size(void)
{
	return sizeof(code);
}

UINT8 mem_read(UINT16 address)
{
	if (address <= 0x7FFF)
		return code[address];
	else
		return ram[address - 0x8000];
		
	/* GB VERO */
	
	/* se l'indirizzo è per la ROM o per la RAM della cartridge forwarda al gestore della cart */
	if (address <= 0x7FFF || (address >= 0xA000 && address <= 0xBFFF))
		return gb_cart_read(address);
	/* working ram banco 0 */
	else if (address >= 0xC000 && address <= 0xCFFF)
	{
		UINT16 offset = address - 0xC000;		
		return memory.wram_bank_0[offset];
	}
	/* working ram banco 1 (switchabile in CGB) */
	else if (address >= 0xD000 && address <= 0xDFFF)
	{
		UINT16 offset = address - 0xD000;		
		return memory.wram_bank_1[offset];
	}
	/* mirror working ram banco 0 */
	else if (address >= 0xE000 && address <= 0xFDFF)
	{
		UINT16 offset = address - 0xE000;		
		return memory.wram_bank_0[offset];
	}
	
	return 0;
		
}

void mem_write(UINT16 address, UINT8 value)
{
	if (address > 0x7FFF)
		ram[address - 0x8000] = value;
	
	return;
	
	/* GB VERO */
	
	/* se indirizzo è per la ROM o per la RAM esterna passa al gestore della cart */
	if (address <= 0x7FFF || (address >= 0xA000 && address <= 0xBFFF))
		gb_cart_write(address, value);
	/* working ram banco 0 */
	else if (address >= 0xC000 && address <= 0xCFFF)
	{
		UINT16 offset = address - 0xC000;		
		memory.wram_bank_0[offset] = value;
	}
	/* working ram banco 1 (switchabile in CGB) */
	else if (address >= 0xD000 && address <= 0xDFFF)
	{
		UINT16 offset = address - 0xD000;		
		memory.wram_bank_1[offset] = value;
	}
	/* mirror working ram banco 0 */
	else if (address >= 0xE000 && address <= 0xFDFF)
	{
		UINT16 offset = address - 0xE000;		
		memory.wram_bank_0[offset] = value;
	}
	
}

/* dealloca tutto e rialloca nuova fiammante memoria */
void mem_init()
{
	memset(ram, 0, 8192);
	
	free(memory.vram_bank);
	free(memory.wram_bank_0);
	free(memory.wram_bank_1);
	free(memory.oam_table);
	
	memory.vram_bank = NULL;
	memory.wram_bank_0 = NULL;
	memory.wram_bank_1 = NULL;
	memory.oam_table = NULL;
	
	memory.vram_bank = (UINT8*) malloc(8192);
	memory.wram_bank_0 = (UINT8*) malloc(8192);
	memory.wram_bank_1 = (UINT8*) malloc(8192);
	memory.oam_table = (UINT8*) malloc(160);
	
	memset(memory.vram_bank, 0x00, 8192);
	memset(memory.wram_bank_0, 0x00, 8192);
	memset(memory.wram_bank_1, 0x00, 8192);
	memset(memory.oam_table, 0x00, 160);
	
}